package structtag

import (
	"encoding/json"
	"fmt"
	"reflect"
)

type Info struct {
	//单纯的struct,能表述的信息是有限的
	Name   string `json:"name"` //name是映射成mysql中的char还是varchar?
	Age    int    `json:"age"`
	Gender string `json:"-"` //这里-的意义是，序列化的时候，不把这个字段序列化
}

//反射
type Info2 struct {
	//单纯的struct,能表述的信息是有限的
	Name   string `orm:"name, max_length=17, min_length=5"` //name是映射成mysql中的char还是varchar?
	Age    int    `orm:"age,  min=18, max=70"`
	Gender string `orm:"gender, required"`
}

func StructTagLearn() {
	//结构体标签
	/*
		结构体的字段除了名字和类型外，还可以有一个可选的标签（tag)
		他是一个附属于字段的字符串，可以是文档或者其他重要标记。比如我们解析json或者生成json字符串时，常用到的encoding/json包。
		它提供一些默认的标签，例如：omitempty标签，可以在序列化的时候忽略0值或者空值。
		而标签的作用是不进行序列化，其效果和直接将结构体的中的字段，写成小写的效果一样。
	*/

	info := Info{
		Name:   "bobby",
		Gender: "男",
	}
	s, _ := json.Marshal(info)
	fmt.Println(string(s))

	fmt.Println("反射。。。")

	t := reflect.TypeOf(Info2{})
	fmt.Println("Type: ", t.Name())
	fmt.Println("Kind: ", t.Kind())

	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i) //获取结构体的每一个字段
		tag := field.Tag.Get("orm")
		fmt.Printf("%d. %v (%v), tag:'%v'\n", i+1, field.Name, field.Type, tag)
	}

	//具体的应用，绝大部分情况下，我们是不需要使用到反射的，实际开发的项目中会用到的

}
